package cn.shujuhai.cms.service.thymeleaf;

import cn.dev33.satoken.stp.StpUtil;
import cn.shujuhai.cms.domain.ArticleParam;
import cn.shujuhai.cms.domain.InfoArticle;
import cn.shujuhai.cms.domain.InfoChannel;
import cn.shujuhai.cms.mapper.ArticleParamMapper;
import cn.shujuhai.cms.mapper.InfoArticleMapper;
import cn.shujuhai.common.aop.SysLogAspect;
import cn.shujuhai.common.mapper.SysUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: zhangDeZhong
 * @Date: 2024/12/5 12:01
 * @Description: 提供模板中信息文章的工具类
 **/
@Component
@RequiredArgsConstructor
public class InfoTool {

    private final InfoArticleMapper infoArticleMapper;
    private final SysUserMapper sysUserMapper;
    private final ArticleParamMapper articleParamMapper;
    private final static String infoCode = "info_admin";
    private static final Logger logger = LoggerFactory.getLogger(SysLogAspect.class);


    /**
     * 根据栏目ID获取对应的一篇文章
     *
     * @param channelId 栏目ID
     * @param state     状态（0：查看，1：生成静态文件）
     * @return 一篇文章
     */
    public InfoArticle oneInfo(Long channelId, Long state) {
        boolean flag = true;
        if (state == 0) {
            try {
                if (StpUtil.isLogin()) {
                    List<String> permissionCodeList = sysUserMapper.selectPermissionCodesByUserId(StpUtil.getLoginIdAsLong());
                    if (permissionCodeList.contains(infoCode)) {
                        flag = false;
                    }
                }
            } catch (Exception e) {
                logger.warn(e.getMessage());
            }
        }
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .select("c.content")
                .leftJoin("info_content c ON c.article_id = t.article_id")
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(flag, InfoArticle::getStatus, 2);
        return this.infoArticleMapper.selectOne(wrapper);
    }

    public InfoArticle oneInfo(Long channelId) {
        boolean flag = true;
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .select("c.content")
                .leftJoin("info_content c ON c.article_id = t.article_id")
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(flag, InfoArticle::getStatus, 2);
        return this.infoArticleMapper.selectOne(wrapper);
    }

    /**
     * 根据栏目ID获取文章列表
     *
     * @param channelId 栏目ID
     * @return 文章列表
     */
    public List<InfoArticle> infoList(Long channelId) {
        boolean flag = true;
        try {
            if (StpUtil.isLogin()) {
                List<String> permissionCodeList = sysUserMapper.selectPermissionCodesByUserId(StpUtil.getLoginIdAsLong());
                if (permissionCodeList.contains(infoCode)) {
                    flag = false;
                }
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }

        // 查询文章列表
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(flag, InfoArticle::getStatus, 2)
                .orderByAsc(InfoArticle::getSort)
                .orderByDesc(InfoArticle::getArticleTime);

        List<InfoArticle> articles = this.infoArticleMapper.selectList(wrapper);

        // 为每篇文章查询参数集合
        for (InfoArticle article : articles) {
            Long articleId = article.getArticleId();
            List<ArticleParam> params = articleParamMapper.selectList(
                    new LambdaQueryWrapper<ArticleParam>()
                            .eq(ArticleParam::getArticleId, articleId)
            );
            article.setInfoParam(params); // 设置参数集合
        }
        return articles;
    }

    /**
     * 根据栏目ID和是否排序获取排序的文章列表
     *
     * @param channelId 栏目ID
     * @param isAsc     是否升序
     * @return 文章列表
     */
    public List<InfoArticle> infoListBySort(Long channelId, boolean isAsc) {
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(InfoArticle::getStatus, 2)
                .orderBy(true, isAsc, InfoArticle::getSort);
        return this.infoArticleMapper.selectList(wrapper);

    }

    /**
     * 根据栏目ID和分页参数获取文章列表
     *
     * @param channelId 栏目ID
     * @param pageNum   页码
     * @param pageSize  每页大小
     * @return 分页信息
     */
    public PageInfo<InfoArticle> infoPage(Long channelId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(InfoArticle::getStatus, 2)
                .orderByAsc(InfoArticle::getSort)
                .orderByDesc(InfoArticle::getArticleTime);
        List<InfoArticle> infoArticleList = this.infoArticleMapper.selectList(wrapper);
        return new PageInfo<>(infoArticleList);
    }

    /**
     * 根据栏目ID获取前num条的文章列表
     *
     * @param channelId 栏目ID
     * @param num       条数
     * @return 文章列表
     */
    public List<InfoArticle> top(Long channelId, Integer num) {
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(InfoArticle::getStatus, 2)
                .last("limit " + num);
        return this.infoArticleMapper.selectList(wrapper);
    }

    /**
     * 根据栏目ID获取排序值前num条文章列表
     *
     * @param channelId 栏目ID
     * @param num       条数
     * @return 文章列表
     */
    public List<InfoArticle> topSort(Long channelId, Integer num) {
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(InfoArticle::getStatus, 2)
                .orderByAsc(InfoArticle::getSort)
                .last("limit " + num);
        return this.infoArticleMapper.selectList(wrapper);
    }

    /**
     * 根据栏目ID获取随机num条文章列表
     *
     * @param channelId 栏目ID
     * @param num       条数
     * @return 随机文章列表
     */
    public List<InfoArticle> randomList(Long channelId, Integer num) {
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .leftJoin(InfoChannel.class, InfoChannel::getArticleId, InfoArticle::getArticleId)
                .eq(InfoChannel::getChannelId, channelId)
                .eq(InfoArticle::getStatus, 2);
        List<Long> ids = this.infoArticleMapper.selectList(wrapper)
                .stream()
                .map(InfoArticle::getArticleId)
                .collect(Collectors.toList());
        if (ids.isEmpty()) {
            return Collections.emptyList();
        }
        Collections.shuffle(ids);
        List<Long> randomIds = ids.stream().limit(num).collect(Collectors.toList());
        return this.infoArticleMapper.selectList(Wrappers.<InfoArticle>lambdaQuery()
                .in(InfoArticle::getArticleId, randomIds)
        );

    }

    /**
     * 根据文章ID获取文章详细
     *
     * @param articleId 文章ID
     * @return 文章详细信息
     */
    public InfoArticle findById(Long articleId) {
        boolean flag = true;
        try {
            if (StpUtil.isLogin()) {
                List<String> permissionCodeList = sysUserMapper.selectPermissionCodesByUserId(StpUtil.getLoginIdAsLong());
                if (permissionCodeList.contains(infoCode)) {
                    flag = false;
                }
            }
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        var wrapper = new MPJLambdaWrapper<InfoArticle>()
                .selectAll(InfoArticle.class)
                .select("c.content")
                .leftJoin("info_content c ON c.article_id = t.article_id")
                .eq(InfoArticle::getArticleId, articleId)
                .eq(flag, InfoArticle::getStatus, 2);
        InfoArticle article = this.infoArticleMapper.selectOne(wrapper);

        if (article != null) {
            // 查询文章参数集合
            List<ArticleParam> params = articleParamMapper.selectList(
                    new LambdaQueryWrapper<ArticleParam>()
                            .eq(ArticleParam::getArticleId, articleId)
            );
            article.setInfoParam(params); // 设置参数集合
        }

        return article;
    }

    /**
     * 全站检索文章
     *
     * @param key      搜索关键字
     * @param pageNum  页码
     * @param pageSize 每页大小
     * @return 分页信息
     */
    public PageInfo<InfoArticle> searchInfo(String key, Integer pageNum, Integer pageSize) {
//        PageHelper.startPage(pageNum, pageSize);
//        var wrapper = new MPJLambdaWrapper<InfoArticle>()
//                .selectAll(InfoArticle.class)
//                .select("c.content")
//                .leftJoin("info_content c ON c.article_id = t.article_id")
//                .select("sc.url_key")
//                .leftJoin("sys_channel sc ON sc.channel_id = t.channel_id")
//                .eq(InfoArticle::getStatus, 2)
//                .and(i -> i
//                        .like(InfoArticle::getTitle, key)
//                        .or().like(InfoArticle::getDescription, key)
//                        .or().like("c.content", key));
//        List<InfoArticle> articles = this.infoArticleMapper.selectList(wrapper);
        System.out.println(key);
        PageHelper.startPage(pageNum, pageSize);
        List<InfoArticle> infoArticleList = this.infoArticleMapper.search_list(key);
        return new PageInfo<>(infoArticleList);
    }


}
